<?php

namespace Lite\Utils;

use Lite\Exception\FileNotFoundException;

abstract class FileUtils {

	/**
	 * Retorna si el archivo existe 
	 * 
	 * @param string $filePath
	 * @return boolean
	 */
	static function fileExists($filePath){
		return file_exists($filePath);
	}
	
	/**
	 * @param string $fileName 
	 */
	static function isHiddenFileName($fileName) {
		return StringUtils::startsWith($fileName, '.');		
	}
	
	/**
	 * Retorna si la ruta existe y es un archivo
	 * 
	 * @param string $filePath
	 * @return boolean
	 */
	static function isFile($filePath){
		return is_file($filePath);
	}
	
	/**
	 * Retorna si la ruta existe y es un link simbolico
	 * 
	 * @param string $filePath
	 * @return boolean
	 */
	static function isLink($filePath){
		return is_link($filePath);
	}

	/**
	 * Retorna si la ruta es un archivo y es posible leerlo
	 * 
	 * @param string $filePath
	 */
	static function isReadable($filePath){
		return is_readable($filePath);
	}

	/**
	 * Retorna si la ruta es un archivo y es posible escribir en el
	 * 
	 * @param string $filePath
	 */
	static function isWriteable($filePath){
		return is_writeable($filePath);
	}

	/**
	 * Lee todo un archivo
	 * 
	 * @param string $filePath
	 * @return string
	 */
	static function readFile($filePath){
		self::throwIfFileNotFound($filePath);
		return file_get_contents($filePath);
	}

	/**
	 * Obtiene la fecha de creacion de un archivo
	 * 
	 * @param string $filePath
	 * @return string
	 */
	static function getChangedTime($filePath){
		
		if( OsUtils::isWindows() ){
			throw new \RuntimeException(
				__METHOD__ . ' only works on non-Window enviroments'
			);
		}
		
		self::throwIfFileNotFound($filePath);
		return filectime($filePath);
	}
	
	/**
	 * Obtiene la fecha de creacion de un archivo
	 * 
	 * @param string $filePath
	 * @return string
	 */
	static function getCreatedTime($filePath){
		
		if( !OsUtils::isWindows() ){
			throw new \RuntimeException(
				__METHOD__ . ' only works on Window enviroments'
			);
		}
		
		self::throwIfFileNotFound($filePath);
		
		if( self::isLink($filePath)) {
			$stat = lstat($filePath);
			return $stat['ctime'];
		}
		return filectime($filePath);
	}
	
	/**
	 * Obtiene la fecha de modificacion de un archivo
	 * 
	 * @param string $filePath
	 * @return string
	 */
	static function getModifiedTime($filePath){
		self::throwIfFileNotFound($filePath);
		return filemtime($filePath);
	}
	
	/**
	 * Obtiene la fecha de modificacion de un archivo
	 * 
	 * @param string $filePath
	 * @return string
	 */
	static function getAccessedTime($filePath){
		self::throwIfFileNotFound($filePath);
		return fileatime($filePath);
	}
	
	/**
	 * Intenta incluir un archivo
	 * 
	 * @param string $filePath
	 * @return boolean;
	 */
	static function includeFile($filePath) {
		return self::fileExists($filePath) ? include($filePath) : false;
	}
	
	/**
	 * Intenta incluir un archivo. No incluye un archivo incluido previamente
	 * 
	 * @param string $filePath
	 * @return boolean;
	 */
	static function includeOnce($filePath) {
		return self::fileExists($filePath) ? include_once($filePath) : false;
	}
	
	/**
	 * Incluye un archivo
	 * @param string $filePath
	 *
	 * @throw FileNotFoundException si es el archivo no existe o no es leible
	 */
	static function requireFile($filePath) {
		self::throwIfFileNotFound($filePath);
		require $filePath;
	}
	
	/**
	 * Incluye un archivo, si este no fue incluido antes
	 * @param string $filePath
	 *
	 * @throw FileNotFoundException si es el archivo no existe o no es leible
	 */
	static function requireOnce($filePath) {
		self::throwIfFileNotFound($filePath);
		echo $filePath;
		require_once $filePath;
	}
	
	/**
	 *
	 */
	private static function throwIfFileNotFound($filePath) {
		if(!self::fileExists($filePath)) {
			throw new FileNotFoundException("{$filePath} does not exists");
		}
		if(!self::isReadable($filePath)) {
			throw new FileNotFoundException("{$filePath} is not readable");
		}
	} 
}